﻿/* *****************************************************************************************
 
Made by www.Flashphoner.com, all rights reserved.
These sources can only be used for working with Flashphoner server.
If you want use this to create your own application (separate from Flashphoner server) – 
please contact support@flashphoner.com 

******************************************************************************************/

package com.flashphoner.api
{
	import com.flashphoner.api.data.Call;
	import com.flashphoner.api.data.ErrorCodes;
	import com.flashphoner.api.data.ModelLocator;
	import com.flashphoner.api.data.PhoneConfig;
	import com.flashphoner.api.interfaces.API;
	import com.flashphoner.api.interfaces.APINotify;
	import com.flashphoner.api.js.APINotifyJS;
	import com.flashphoner.api.management.PhoneSpeaker;
	import com.flashphoner.api.management.SoundControl;
	import com.flashphoner.api.management.VideoControl;
	
	import flash.events.TimerEvent;
	import flash.external.ExternalInterface;
	import flash.media.Camera;
	import flash.media.Microphone;
	import flash.net.Responder;
	import flash.utils.Timer;

	[Bindable]
	public class Flash_API implements API
	{
		private static var registeredTimer:Timer;
		private static var flash_API:Flash_API;

		internal var phoneServerProxy:PhoneServerProxy = new PhoneServerProxy(new Responder(result,fault));
		internal var currentCall:Call = null;	
		
		public var apiNotify:APINotify;		

		public var modelLocator:ModelLocator = new ModelLocator();
		
		public static function getInstance():Flash_API{
			if (flash_API == null){
				flash_API = new Flash_API();
				PhoneModel.getInstance();
				ExternalInterface.addCallback("getParameters",flash_API.getParameters);
				ExternalInterface.addCallback("login",flash_API.login);
				ExternalInterface.addCallback("loginClick2Call",flash_API.loginClick2Call);
				ExternalInterface.addCallback("call",flash_API.call);
				ExternalInterface.addCallback("hangup",flash_API.hangup);
				ExternalInterface.addCallback("answer",flash_API.answer);
				ExternalInterface.addCallback("sendDTMF",flash_API.sendDTMF);
				ExternalInterface.addCallback("getMicVolume",flash_API.getMicVolume);
				ExternalInterface.addCallback("setMicVolume",flash_API.setMicVolume);
				ExternalInterface.addCallback("getVolume",flash_API.getVolume);
				ExternalInterface.addCallback("setVolume",flash_API.setVolume);
				ExternalInterface.addCallback("getMicropones",flash_API.getMicropones);
				ExternalInterface.addCallback("setMicrophone",flash_API.setMicrophone);
				ExternalInterface.addCallback("getCameras",flash_API.getCameras);
				ExternalInterface.addCallback("setCamera",flash_API.setCamera);
				ExternalInterface.addCallback("logoff",flash_API.logoff);
				flash_API.addAPINotify(new APINotifyJS());
			}
			return flash_API;
		}
		
		public function Flash_API()
		{
		}
		
		public function getCall():Call{
			return currentCall;
		}
		
		public function getPhoneSpeaker():PhoneSpeaker{
			return this.phoneServerProxy.phoneSpeaker;
		}
		
		public function addAPINotify(apiNotify:APINotify):void{
			this.apiNotify = apiNotify;
		}
		
		public function getAPINotify():APINotify{
			return apiNotify;
		}
		public function getParameters():Object{
			var object:Object = PhoneModel.getInstance().parameters;
			if (object == null){
				return ErrorCodes.PARAMETERS_IS_NOT_INITIALIZED;				
			}else{
				return PhoneModel.getInstance().parameters;
			}
		}
		public function login(username:String,password:String):int{
			ExternalInterface.call("notifyRegisterRequired",PhoneConfig.REGISTER_REQUIRED);
			if (PhoneConfig.REGISTER_REQUIRED){
				PhoneModel.getInstance().upRegisteredTimer();
				PhoneModel.getInstance().startRegisterTimer();
			}
			return phoneServerProxy.login(username,password);							
		}
		
		public function loginClick2Call():void{
			ExternalInterface.call("notifyRegisterRequired",PhoneConfig.REGISTER_REQUIRED);
			if (PhoneConfig.REGISTER_REQUIRED){
				PhoneModel.getInstance().upRegisteredTimer();
				PhoneModel.getInstance().startRegisterTimer();
			}
			phoneServerProxy.login();							
		}		
		public function call(callee:String, visibleName:String, isVideoCall:Boolean = false):int{
			if (PhoneConfig.CHECK_VALIDATION_CALLEE){
				var reg:RegExp = /[a-zа-яё]/i;
				if (callee != null && callee != ""){
					if (flash_API.modelLocator.mode == "flashphoner"){
						if ((callee.indexOf("sip:") == 0)){
							if (callee.indexOf("@") == -1 || callee.indexOf("@") == callee.length-1){
								return 1;
							}
						}else{
							if (callee.search(reg) != -1){
								if (callee.indexOf("@") != -1){
									return 1;
								}
								if (callee.indexOf(":") != -1){
									return 1;
								}
								callee = "sip:"+callee+"@"+modelLocator.sipProviderAddress+":"+modelLocator.sipProviderPort;
							}
						}
					}else{
						return 1;
					}
				}else{
					if (flash_API.modelLocator.mode != "click2call"){
						return 1;
					}
				}
			}
			if (visibleName != null){
				visibleName.replace("\"","");
				visibleName.replace("\'","");
			}
			phoneServerProxy.call(visibleName,callee,isVideoCall);
			return 0;
		}
		
		public function hangup():void{
			if (currentCall!=null){
				phoneServerProxy.unpublish(currentCall);	
				phoneServerProxy.hangup(currentCall);										
			}	
			SoundControl.getInstance().stopRingSound();
		}
		
		public function answer(isVideoCall:Boolean = false):void{
			SoundControl.getInstance().stopRingSound();
			phoneServerProxy.answer(currentCall,isVideoCall);			
		}
		public function isSendVideo(flag:Boolean):void{
			phoneServerProxy.isSendVideo(flag);		
		} 
				
		public function sendDTMF(dtmf:String):void{
			phoneServerProxy.sendDtmf(currentCall,dtmf);			
		}		
		public function getMicVolume():int{
			return SoundControl.getInstance().getMicrophone().gain;
		}
		
		public function setMicVolume(volume:int):void{
			SoundControl.getInstance().getMicrophone().gain = volume;
		}
		
		public function getVolume():int{
			return flash_API.phoneServerProxy.phoneSpeaker.getVolume();
		}
		
		public function setVolume(volume:int):void{
			flash_API.phoneServerProxy.phoneSpeaker.setVolume(volume);
		}
		
		public function getMicropones():Array{
			return Microphone.names;
		}
		
		public function setMicrophone(name:String):void{
			var i:int = 0;
			for each (var nameMic:String in Microphone.names){
				if (nameMic == name){
					SoundControl.getInstance().changeMicrophone(Microphone.getMicrophone(i),false);
					return;						
				}
				i++;				
			}
		}
		
		public function getCameras():Array{
			return Camera.names;
		}
		
		public function setCamera(name:String):void{
			VideoControl.getInstance().changeCamera(Camera.getCamera(name));
		}
		
		public  function logoff():void{
			phoneServerProxy.disconnect();
		}
		
		private function upRegisteredTimer():void{
			if (registeredTimer!=null){
				registeredTimer.stop();
					
			} else {
				registeredTimer = new Timer(10000);
				registeredTimer.addEventListener(TimerEvent.TIMER,registeredExpire);					
			}
		}
		
		private function dropRegisteredTimer():void{
			if (registeredTimer!=null){
				registeredTimer.stop();
				registeredTimer.removeEventListener(TimerEvent.TIMER,registeredExpire);
				registeredTimer=null;
			}
		}
		
		private function registeredExpire(event:TimerEvent):void{
			//phoneModel.phoneViewController.registerAttemptExpire();			
			dropRegisteredTimer();			
		}			
		
		private function fault(data : Object) : void
		{
		}		
		
		private function result(_call : Object) : void
		{
			var call:Call = new Call();
			call.id = _call.id;
			call.state = _call.state;
			call.incoming=false;							
			currentCall=call;
		}		
		

	}
}